package com.nowar.data.interceptor;

import com.nowar.data.annotation.ShardingStrategy;
import com.nowar.data.constant.DataConstant;
import com.nowar.data.frame.DataSource;
import com.nowar.data.frame.util.RoutingKeyUtil;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * Executor拦截器
 *
 * @Author: 谢无殇。
 * @Date : 2023-01-16 00:11
 */
@Component
@Intercepts({
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class DynamicInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        MappedStatement mappedStatement = (MappedStatement) args[0];
        String id = mappedStatement.getId();
        //反射
        String className = id.substring(0, id.lastIndexOf("."));
        String methodName = id.substring(id.lastIndexOf(".") + 1);
        Class<?> clazz = Class.forName(className);
        ShardingStrategy shardingStrategy = null;
        for (Method method : clazz.getMethods()) {
            if (method.getName().equals(methodName)) {
                shardingStrategy = method.getAnnotation(ShardingStrategy.class);
                // todo
                break;
            }
        }
        // 设置数据及数据库
        if (shardingStrategy != null) {
            setRoutingKey(shardingStrategy, args[1]);
        } else {
            //默认主库
            DataSource.setRoutingKey(DataConstant.DATA_SOURCE_KEY);
        }
        return invocation.proceed();
    }

    private void setRoutingKey(ShardingStrategy shardingStrategy, Object parameter) {
        if (parameter instanceof Map) {
            Map<String, Object> parameterMap = (Map<String, Object>) parameter;
        }
        // 获取方法上的参数，进行计算数据库
        Class<?>[] shardingJdbc = shardingStrategy.shardingJdbc();
        if (shardingJdbc.length == 1) {
        }
        Class<?>[] shardingTable = shardingStrategy.shardingTable();
        if (shardingTable.length == 1) {

        }
    }
}
